package spe.ui.wizard;

import java.io.File;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

import spe.model.spem.MethodLibrary;
import spe.model.spem.SPEMFactoryImpl;

/**
 * @author Dao Anh Vu
 * @since 1.0
 * */
public class NewMethodLibraryWizardPage extends WizardPage implements Listener
{
	public static final String PAGE_NAME = NewMethodLibraryWizardPage.class.getName();
	
	//private Shell shell;
	private Text txtSPEProject;
	private Text txtMethodLibraryName = null;
	private IWorkspaceRoot workspaceRoot;
	
	//This is used for data
	private MethodLibrary methodLibrary;
	private String containerName;
	
	public NewMethodLibraryWizardPage() 
	{
		super(PAGE_NAME);
		setTitle("Create New Method Library");
		workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
	}
	
	public void init(IStructuredSelection selection)
	{
		IContainer container = null;
		if (selection != null && !selection.isEmpty()) 
		{	
			Object object = selection.getFirstElement();
			if (IFile.class.isInstance(object) && !IContainer.class.isInstance(object)) {
				container = ((IFile)object).getParent();
			} else if (IContainer.class.isInstance(object)) {
				container = (IContainer)object;
			}
		}
		initContainerName(container);
	}

	@Override
	public void createControl(Composite parent) 
	{
		initializeDialogUnits(parent);
		Composite clientArea = createClientArea(parent);
		createLabelField(clientArea);
		createContainerField(clientArea);
		createLibraryField(clientArea);
		setControl(clientArea);
		Dialog.applyDialogFont(clientArea);		
		setPageComplete(false);
	}
	
	private void initContainerName(IContainer elem)
	{
		containerName = (elem == null) ? "" : elem.getFullPath().makeRelative().toString(); 
	}
	
	private void createLabelField(Composite clientArea)
	{
		Label label= new Label(clientArea, SWT.WRAP);
		label.setText("Choose a project and a method library name.");
		GridData gd= new GridData();
		gd.widthHint= convertWidthInCharsToPixels(80);
		gd.horizontalSpan= 3;
		label.setLayoutData(gd);
		
		/*
		FormLayout layout = new FormLayout();
		c.setLayout(layout);
		
		FormData fd = new FormData();
		Label lb = new Label(c, SWT.NONE);
		lb.setText("Method library name ");
		lb.setLayoutData(fd);
		
		fd = new FormData();
		fd.left = new FormAttachment(lb, 5, SWT.RIGHT);
		fd.right = new FormAttachment(100, -5);
		txtMethodLibraryName = new Text(c, SWT.BORDER);
		txtMethodLibraryName.addListener(SWT.Traverse, this);
		txtMethodLibraryName.setLayoutData(fd);
		
		txtMethodLibraryName.addModifyListener(new ModifyListener(){
			public void modifyText(ModifyEvent e)
			{
				String str = txtMethodLibraryName.getText();
				Status status = new Status(IStatus.OK, "not_used", 0, "Create new method library.", null);
				//System.out.println("Event handled");
				
				if( (str.length()<= 0) || str.contains(";"))
					status = new Status(IStatus.ERROR, "not_used", 0, "Method library name is not valid.", null);
				
				applyStatus(status);			
			}
		});
		
		Label label = new Label(c, SWT.NONE);
		label.setText("Source folder : ");
		txtLibraryFolder = new Text(c, SWT.BORDER);
		txtLibraryFolder.setText(containerName);
		txtLibraryFolder.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				//verifyContentsValid();
				String str = txtLibraryFolder.getText();
				Status status = new Status(IStatus.OK, "not_used", 0, "Create new method library.", null);
				//System.out.println("Event handled");
				
				if( (str.length()<= 0) || str.contains(";"))
					status = new Status(IStatus.ERROR, "not_used", 0, "Folder is not valid.", null);
				
				applyStatus(status);
			}
		});
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		txtLibraryFolder.setLayoutData(gd);
		browseButton = new Button(c, SWT.PUSH);
		browseButton.setText("Browse...");
		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				chooseContainer();
			}			
		});
		gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(15);
		browseButton.setLayoutData(gd);
		
		setErrorMessage("Enter library name");
		setPageComplete(false);
		*/
	}
	
	private Composite createClientArea(Composite parent) 
	{
		Composite composite= new Composite(parent, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		layout.numColumns= 2;
		composite.setLayout(layout);
		return composite;
	}
	
	private void createContainerField(Composite parent) 
	{
		Label label = new Label(parent, SWT.NONE);
		label.setText("Project : ");
		txtSPEProject = new Text(parent, SWT.BORDER);
		txtSPEProject.setText(containerName);
		txtSPEProject.setEditable(false);
		
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		txtSPEProject.setLayoutData(gd);
		gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(15);
	}
	
	private void createLibraryField(Composite parent) 
	{
		Label label = new Label(parent, SWT.NONE);
		label.setText("Method library name : ");
		txtMethodLibraryName = new Text(parent, SWT.BORDER);
		txtMethodLibraryName.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				verifyContentsValid();
			}
		});
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		txtMethodLibraryName.setLayoutData(gd);		
	}
	
	private void verifyContentsValid() 
	{
		// TODO Auto-generated method stub
		if (isLibraryNameEmpty()) {
			setErrorMessage("Enter a name for the process.");
			setPageComplete(false);
		} else if (libraryExists()){
			setErrorMessage("A process with this name already exists.");
			setPageComplete(false);
		} else {
			setErrorMessage(null);
			setPageComplete(true);
		}
	}

	private boolean libraryExists() 
	{
		IPath path = new Path(txtSPEProject.getText()).append(txtMethodLibraryName.getText());
		return workspaceRoot.getFolder(path).exists();
	}

	private boolean isLibraryNameEmpty() {
		String str = txtMethodLibraryName.getText();
		return str == null || "".equals(str);
	}

	private boolean checkContainerPathValid() 
	{
		if ("".equals(txtSPEProject.getText())) {
			return false;
		}
		IPath path = new Path(txtSPEProject.getText());
		return workspaceRoot.getFolder(path).exists();
	}
	
	private ViewerFilter createViewerFilter() 
	{
		ViewerFilter filter= new ViewerFilter() 
		{
			public boolean select(Viewer viewer, Object parent, Object element) 
			{
				//return IFolder.class.isInstance(element) || IProject.class.isInstance(element);
				//return IFolder.class.isInstance(element);
				return ((element instanceof File) && ((File)element).isDirectory());
			}
		};
		return filter;
	}
	
	@Override
	public IWizardPage getNextPage()
	{
		IWizardPage nextPage = super.getNextPage();
		if(nextPage == null)
		{
			
		}
		return nextPage;
	}
	
	public MethodLibrary getMethodLibrary()
	{
		if(methodLibrary == null)
			methodLibrary = (MethodLibrary) SPEMFactoryImpl.createInstance("spe.ui.editor").createElementById("MethodLibrary");
		
		//methodLibrary.setName(txtMethodLibraryName.getText());
		return methodLibrary;
	}
	
	public String getMethodLibraryName()
	{
		return txtMethodLibraryName.getText();
	}
	
	@Override
	public void handleEvent(Event event)
	{
		String str;
		Status status = new Status(IStatus.OK, "not_used", 0, "", null);
		//System.out.println("Event handled");
		if(event.widget == txtMethodLibraryName)
		{
			str = txtMethodLibraryName.getText().trim();
			if( (str.length()<= 0) || str.contains(";"))
				status = new Status(IStatus.ERROR, "not_used", 0, "Method library name is not valid.", null);
		}
		
		applyStatus(status);
	}
	
	private void applyStatus(Status status)
	{
		switch(status.getSeverity())
		{
			case IStatus.OK:
				setMessage(status.getMessage());
				setErrorMessage(null);
				setPageComplete(true);
				break;
				
			case IStatus.WARNING:
				break;
				
			case IStatus.ERROR:
				setErrorMessage(status.getMessage());
				setPageComplete(false);
				break;
		}
	}
	
	public IFolder getMethodLibraryFolder()
	{
		 //IPath path = new Path(txtSPEProject.getText()).append(txtMethodLibraryName.getText());
		IPath path = new Path(txtSPEProject.getText()).append("models");
		 return workspaceRoot.getFolder(path); 
	}

}
